docs(plugin-dashboard): README's chart example taught a rejected type: 'card' widget - #7951
Merged
baozhoutao merged 1 commit intoSep 6, 2026
Conversation
…e: 'card'` widget (objectui#7035) The "Dashboard with Charts" example put two widgets spelled `type: 'card'` with a nested `body` into `widgets[]`. `'card'` is not a member of `DashboardWidgetTypeName` — the vocabulary objectui#4600 closed — so `@object-ui/types/zod`'s `DashboardComponentSchema.safeParse` refuses the whole document. Measured on the shipped contract, not read off the type: the block returned `invalid_union` at `widgets[1]` and `widgets[2]`. Rendered unvalidated, the first one's `body` names `line-chart`, which nothing registers, so it paints the registry's OBJUI-001 panel. Both are now the chart-family widgets the renderer actually dispatches — `line` and `pie`, with their inline rows under `options.data` and `options.xField` / `options.yField` — plus one paragraph stating the rule the example now follows. The new test parses every dashboard example on the page through the shipped schema. No gate asked that question before: `check:doc-snippets` compiles fenced blocks and these are untyped literals, `check:doc-types` covers `content/docs/**` and the root README only, and `check:readme-exports` judges imports. Verified by reverting the block: the test goes red on exactly those two widgets. The three `type: 'metric-card'` examples are deliberately untouched — the 2026-08-14 maintainer ruling (objectstack#8593) admits that component node into the widget slot, and both the Zod union and the renderer accept it as written. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M
This was referenced Sep 6, 2026
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
baozhoutao
marked this pull request as ready for review
September 6, 2026 04:27
baozhoutao
deleted the
claude/issue-7035-dashboard-readme-rejected-widget-shapes
branch
September 6, 2026 04:49
This was referenced Sep 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7035
The README's "Dashboard with Charts" example put two widgets spelled
type: 'card'with anested
bodyintowidgets[]. Measured, not read off the type:@object-ui/types/zod'sDashboardComponentSchema.safeParsereturnsinvalid_unionatwidgets[1]andwidgets[2],so a reader who copied the block got a rejection.
'card'is not a member ofDashboardWidgetTypeName, the vocabulary #4600 closed.Both are now the chart-family widgets the renderer actually dispatches —
lineandpie,with inline rows under
options.dataandoptions.xField/options.yField— plus oneparagraph stating the rule the example now follows.
The card's population is smaller than the measurement predicted — and the other half is a fork, not a fix
Comment
5523309430widened this card from one fence to four blocks that put acomponent-shaped node straight into
widgets[], leaving open which side was wrong.Measured on
a2e10cf96, the answer splits, and only one half is a docs defect::48quick start —type: 'metric-card':178Basic Dashboard — threemetric-card:217Dashboard with Charts — twotype: 'card'invalid_union×2bodynamesline-chart, which nothing registers, so the registry paints its OBJUI-001 panel:275Data Sources —type: 'metric-card'metric-cardin a widget slot is not an accident of tolerance:DASHBOARD_COMPONENT_WIDGET_TYPES(
packages/types/src/complex.ts:1568) admits it by the 2026-08-14 maintainer ruling(objectstack#8593), the Zod widget slot is a union whose first arm is exactly that component node
(
packages/types/src/zod/complex.zod.ts:887over:749), andclassifyWidgetTypereturnspassthroughfor it on purpose. So those three blocks are left byte-untouched.What the same measurement did surface is a divergence this PR deliberately does not touch,
because it lives in
packages/typesand is a published-contract decision:DashboardComponentSchema.widgetsis declaredDashboardWidgetSchema[](
complex.ts:1733) with no component-node arm, so annotating the legalmetric-cardexamplesyields
TS2561: 'value' does not exist in type 'DashboardWidgetSchema'— the Zod mirror acceptsa whole arm the TypeScript declaration refuses. That is filed as #7952 and is not addressed
here — it is a
packages/typesdecision, and #7952 also records why the parity ledger filesthat key as SCHEMA-NODE and so sorts it out of #7759's disposition lane.
What was measured
Everything below ran on
70ea5b79b.Before. The batch-10 diagnostics reproduced against the built
dist/,--strict:Renderer. Each shape rendered through the shipped
DashboardRendererwith@object-ui/plugin-chartsregistered: thetype: 'card'widget paintsUnknown component type: line-chart … (OBJUI-001); the rewrite paints two charts and no OBJUI-001; a mis-spelledtypestays red. (Scratch harness, not committed.)After. Every dashboard block extracted from the file — not retyped — parses:
Ablation. Reverting the block to the
type: 'card'spelling turns the new test red onexactly that block, naming both widgets — mutation proven on disk (
type: 'card'count 0→2,type: 'line',count 1→0, blob hash changed), restore proven byte-identical to theHEADblob:Why a test file
No gate asked this question, each for a stated reason:
check:doc-snippetscompiles fencedtsand these are untypedconst schema = { … }literals (its header names schema-keyvalidity as the question it does not answer);
check:doc-typeswalkscontent/docs/**and theroot README, so package READMEs are outside it (#7896, whose live-instance list this README's
unregistered
line-chartjoins);check:readme-exportsjudges import bindings. The new test isthis document only, and follows
plugin-gantt/src/readme-navigation-example.test.ts— the samepattern one package over.
Gates
pnpm check:doc-snippetsEvery covered documentation snippet compiles against the built types.(467/467 judged, 0 failed)pnpm check:doc-fences✅ check:doc-fences — every TypeScript block in 227 document(s) is fenced ts/tsx/typescript…pnpm check:doc-types✅ Every documented component type is registered.pnpm check:readme-exports✅ check-readme-exports: OK (43 tracked README(s)…)pnpm check:control-bytes✅ check-control-bytes: OK (scanned 6410 tracked text file(s); skipped 85 binary).node scripts/check-changeset-presence.mjs✅ … declares 1 changeset(s) … Every one of them has an EMPTY frontmatter — declared as releasing nothingnode scripts/check-changeset-no-major.mjs✅ No changeset declares amajorbump.node scripts/check-governed-queue-guard.mjs --test THE-3-PATHS✅ NOT GOVERNED — 3 path(s) checked against 5 governed surface(s); none matched.vitest run packages/plugin-dashboard/Test Files 94 passed (94) · Tests 846 passed (846)vitest run examples/schema-catalog/test/plugin-dashboard-component-schema.test.tsTest Files 1 passed (1) · Tests 21 passed (21)— the standing widget-slot contract gatepnpm --filter @object-ui/plugin-dashboard type-checktsc -p tsconfig.test.json --listFilesnames it)pnpm --filter @object-ui/plugin-dashboard lint✖ 426 problems (0 errors, 426 warnings)— all pre-existingno-explicit-anyThe repo-wide
pnpm lintand the rest of the farm are CI's.Generated by Claude Code